package com.springcloud.sc.ucpv5.client.application.message.connect;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import com.springcloud.sc.ucpv5.client.application.message.type.shortType.UnShort_Wrap;
import com.springcloud.sc.ucpv5.client.commondata.datachange.DataExChange;

public abstract class ConnectFather implements ConnectInterface {

    // 保存收到的记录,做前台接受处理
    protected BlockingQueue msgQueueFromServer = new ArrayBlockingQueue(10000);

    // 保存收到的记录,做后台发送处理
    protected BlockingQueue<MessageData> msgQueueToServer = new ArrayBlockingQueue<MessageData>(10000);

    private Thread doDataToServerThread = null;
    private Thread doDataFromServerThread = null;

    private boolean isStop = false;

    protected int sessionId = 0;

    public ConnectFather() {
	isStop = false;
	doDataToServerThread = new Thread() {
	    public void run() {
		// 发包循环
		while (!isStop) {
		    try {
			// 转换, 并发送处理
			if (msgQueueToServer.isEmpty()) {
			    Thread.sleep(1);
			} else {
			    doDataToServer(msgQueueToServer.poll());
			}
		    } catch (Exception e) {
			e.printStackTrace();
		    }
		}
	    }
	};
	doDataFromServerThread = new Thread() {
	    public void run() {
		// 收包循环
		while (!isStop) {
		    try {
			// 转换, 并发送内部处理
			if (msgQueueFromServer.isEmpty()) {
			    Thread.sleep(1);
			} else {
			    doDataFromServer(msgQueueFromServer.poll());
			}
		    } catch (Exception e) {
			e.printStackTrace();
		    }
		}
	    }
	};

	doDataToServerThread.start();
	doDataFromServerThread.start();
    }

    public void doDataToServer(MessageData messageData) {
	try {
	    ;
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

    public void doDataFromServer(Object msg) {
	try {
	    ;
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

    public void stopIt() {
	// TODO Auto-generated method stub
	System.out.println("ConnectFather stopIt");
	isStop = true;
    }

    public void close() {
	System.out.println("ConnectFather  close :" + isStop);
	msgQueueFromServer.clear();
	msgQueueToServer.clear();
	try {
	    if (readThead != null) {
		readThead.setStop(true);
	    }
	} catch (Exception e) {
	    // TODO: handle exception
	}
    }

    private ExecutorService readMsgExecutor = Executors.newSingleThreadScheduledExecutor();
    private Future readMsgFuture;

    private ReadSocketMsgThread readThead;

    public void startReadThread() {
	// 启消息接收线程
	if (readThead != null) {
	    readThead.setStop(true);
	    if (readThead.isStop()) {
		readThead.setStop(false);
		readMsgFuture = readMsgExecutor.submit(readThead);
	    }
	} else {

	    readThead = new ReadSocketMsgThread();
	    readThead.setStop(false);
	    readMsgFuture = readMsgExecutor.submit(readThead);
	}
    }

    public boolean isDatAvailable() {
	return true;
    }

    public class ReadSocketMsgThread implements Runnable {
	private boolean isStop = false;

	public boolean isStop() {
	    return isStop;
	}

	public void setStop(boolean isStop) {
	    this.isStop = isStop;
	}

	public void run() {
	    Thread.currentThread().setName("MessageService.ReadSocketMsgThread");
	    try {
		while (!isStop) {
		    if (!checkConnectOk()) {
			return;
		    }

		    try {
			if (isDatAvailable()) {
			    try {
				if (!readSocketMsg()) {
				    Thread.sleep(10);
				}
			    } catch (IOException e) {
				System.out.println("ReadSocketMsgThread IOException!!!!!!!!!" + e.getMessage());
				throw e;
			    } catch (Throwable e) {
				System.out.println("ReadSocketMsgThread IOException!!!!!!!!!" + e.getMessage());
			    }
			} else {
			    try {
				Thread.sleep(10);
			    } catch (InterruptedException e) {
				// e.printStackTrace();
			    }
			}
		    } catch (Exception e) {
			System.out.println("ReadSocketMsgThread IOException!!!!!!!!!" + e.getMessage());
		    } catch (Throwable e) {
			System.out.println("ReadSocketMsgThread Throwable!!!!!!!!!" + e.getMessage());
		    }
		}
		//System.out.println("ReadSocketMsgThread stop!!!!!!!!!");

	    } catch (Throwable exp) {
		;
	    }
	}
    }

    private boolean readSocketMsg() throws IOException {
	byte[] header = readSocket(2);
	if (header == null) {
	    return false;
	}

	if (header.length < 2) {
	    System.out.println("readSocketMsg Error 0");
	    return false;
	} else {
	}

	if (header[0] != SOCKET_MSG_BEGIN[0] || header[1] != SOCKET_MSG_BEGIN[1]) { // 无效消息包
	    return false;
	}

	byte[] commHeader = readSocket(SOCKET_MSG_LENGTH);
	if (commHeader == null) {
	    return false;
	}
	if (commHeader.length != SOCKET_MSG_LENGTH) {
	    return false;
	}

	ByteBuffer byteBuffer = ByteBuffer.wrap(commHeader);
	int totalLen = UnShort_Wrap.unpackUnShort_uint(byteBuffer, SOCKET_MSG_LENGTH, false);

	if (totalLen < SOCKET_MSG_LENGTH + MSG_HEADER_MIN_LEN) {
	    System.out.println("读取Socket消息体失败：消息长度不正确 ");
	    return false;
	}

	byte[] content = null;

	content = readSocket(totalLen - SOCKET_MSG_LENGTH);
	if (content == null) {
	    return false;
	}
	if (content.length < totalLen - SOCKET_MSG_LENGTH) {
	    System.out.println("header0and5: 读取长度:" + content.length);
	    return false;
	}

	// 判断消息尾
	header = readSocket(2);
	if (header == null) {
	    return false;
	}
	if (header[0] != SOCKET_MSG_END[0] || header[1] != SOCKET_MSG_END[1]) {
	    System.out.println("Fail SOCKET MSG END：");
	    return false;
	} else {
	    // System.out.println("Socket返回: 结尾正确:");
	}

	// 解压
	try {
	    msgQueueFromServer.put(content);
	} catch (InterruptedException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	return true;
    }

    public int getSessionId() {
	return sessionId;
    }

    public int writeByteMsg(com.springcloud.sc.ucpv5.client.commondata.data.MsgHeader header, DataExChange message) {
	try {
	    MessageData messageData = new MessageData();
	    messageData.header = header;
	    messageData.message = message;
	    msgQueueToServer.put(messageData);
	} catch (Exception e) {
	    // TODO: handle exception
	}

	return 0;
    }

    public void checkShakeHand() {
	;
    }
}
